﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Xml;
//MicroDesigner
using Jc.MicroDesigner.Objects;
using Jc.MicroDesigner.Events;
using Jc.MicroDesigner.Management;
using System.ComponentModel;

namespace Jc.MicroDesigner.Drawings.SpecialObjects
{
    /// <summary>
    /// Простая надпись на холсте
    /// </summary>
    public class TextObject : BaseElement
    {
        private Font _Font = new Font(FontFamily.GenericSerif, 12.0f);
        private Brush _Brush = new SolidBrush(Color.Black);

        /// <summary>
        /// Отрисовка текста на изображении элемента
        /// </summary>
        /// <param name="img">Шаблон</param>
        /// <param name="element">Элемент</param>
        void _DrawOptions_onPaint(Image img, BaseElement element)
        {
            Graphics g = Graphics.FromImage(img);
            //текст выглядит слегка размытым, нужно подобрать параметры как можно лучше
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
            g.DrawString(this._Description, _Font, _Brush, new PointF(0.0f, 0.0f));
        }

        /// <summary>
        /// При обновлении шаблона
        /// </summary>
        /// <param name="element"></param>
        void _DrawOptions_onRefresh(BaseElement element)
        {
            ComputeNewTextSize();
        }

        /// <summary>
        /// Расчитать необходимую площадь для вывода текста
        /// </summary>
        void ComputeNewTextSize()
        {
            Bitmap bmp = new Bitmap(200, 20);
            Graphics g = Graphics.FromImage(bmp);
            SizeF sizeF = g.MeasureString(this._Description, _Font);
            int w = Convert.ToInt32(Math.Round(sizeF.Width) + 1);
            int h = Convert.ToInt32(Math.Round(sizeF.Height) + 1);
            if ((h != _DrawOptions.Height) || (w != _DrawOptions.Width))
            {
                this._DrawOptions.Width = w;
                this._DrawOptions.Height = h;
            }
            g.Dispose();
            bmp.Dispose();
        }

        /// <summary>
        /// Загрузить шрифт текста
        /// </summary>
        /// <param name="nodes">Ветви свойств</param>
        public override void LoadAdditionals(Dictionary<ConfigSection, XmlNode> nodes)
        {
            XmlNode add = nodes[ConfigSection.Additionals];
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font));
            TextFont = (Font)converter.ConvertFromString(add.ChildNodes[0].Attributes["value"].Value); 
        }

        /// <summary>
        /// Сохранить шрифт
        /// </summary>
        /// <param name="nodes">Ветви свойств</param>
        public override void SaveAdditionals(Dictionary<ConfigSection, XmlNode> nodes)
        {
            XmlNode add = nodes[ConfigSection.Additionals];
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(Font));
            string value = converter.ConvertToString(this.TextFont);
            XmlNode FontNode = add.OwnerDocument.CreateElement("Font");
            SchemeSerializer.CreateXmlAttr(FontNode, "value", value);
            add.AppendChild(FontNode);
        }

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="text">Текст</param>
        /// <param name="name">Имя</param>
        public TextObject(string text, string name)
            : base(name)
        {
            _Description = text;
            _DrawOptions.onPaint += new onPaintElement(_DrawOptions_onPaint);
            _DrawOptions.onRefresh += new onRefreshTemplate(_DrawOptions_onRefresh);
            ComputeNewTextSize();
        }

        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="name">Имя объекта</param>
        public TextObject(string name) : this(name, name) { }

        /// <summary>
        /// Шрифт
        /// </summary>
        public Font TextFont
        {
            get
            {
                return _Font;
            }
            set
            {
                _Font = value;
                ComputeNewTextSize();
            }
        }
    }
}